package com.laomou.poker.rule.landlord;

import java.util.List;

import com.java.rapid.Condition3;
import com.java.rapid.list.raListGroup;
import com.laomou.poker.Poker;
import com.laomou.poker.PokerGroup;
import com.laomou.poker.PokerNum;
import com.laomou.poker.rule.AbsPokerRule;
import com.laomou.poker.rule.PokerRuleType;

public class Landlord extends AbsPokerRule {

    @Override
    public PokerRuleType getRuleType() {
        return PokerRuleType.斗地主;
    }

    @Override
    public int getPlayerPokerCount() {
        return 17;
    }

    @Override
    public int getPokerCount() {
        return 1;
    }

    @Override
    public boolean isGreater(PokerGroup lp, PokerGroup rp) {
        boolean IsGreater = false;
        if (lp.type() != rp.type()) {
            if (lp.type() == LandlordType.双王) {
                IsGreater = true;
            }
            if (lp.type() == LandlordType.炸弹) {
                IsGreater = true;
            }
        } else {
            if (lp.type() == LandlordType.单顺子 || lp.type() == LandlordType.双顺子
                    || lp.type() == LandlordType.三顺子) {
                if (lp.size() == rp.size()) {
                    if (lp.getValue() > rp.getValue()) {
                        IsGreater = true;
                    }
                }
            } else if (lp.type() == LandlordType.三飞机
                    || lp.type() == LandlordType.四飞机) {
                if (lp.getValue() > rp.getValue()) {
                    IsGreater = true;
                }
            } else if (lp.type() == LandlordType.单牌) {
                if (lp.value() == PokerNum.方块2.value()) {
                    lp.setValue(15);
                }
                if (rp.value() == PokerNum.方块2.value()) {
                    rp.setValue(15);
                }
                if (lp.getValue() > rp.getValue()) {
                    IsGreater = true;
                }
            } else if (lp.type() == LandlordType.对子) {
                if (lp.contains(PokerNum.方块2.value())) {
                    lp.setValue(30);
                }
                if (rp.contains(PokerNum.方块2.value())) {
                    rp.setValue(30);
                }
                if (lp.getValue() > rp.getValue()) {
                    IsGreater = true;
                }
            } else {
                if (lp.getValue() > rp.getValue()) {
                    IsGreater = true;
                }
            }
        }
        return IsGreater;
    }

    @Override
    public boolean isRule(PokerGroup pokerGroup) {
        boolean isRule = false;
        switch (pokerGroup.size()) {
            case 0:
                isRule = false;
                break;
            case 1:
                isRule = true;
                pokerGroup.setType(LandlordType.单牌);
                break;
            case 2:
                if (_isSame(pokerGroup)) {
                    isRule = true;
                    pokerGroup.setType(LandlordType.对子);
                } else {
                    if (pokerGroup.contains(PokerNum.大王)
                            && pokerGroup.contains(PokerNum.小王)) {
                        pokerGroup.setType(LandlordType.双王);
                        isRule = true;
                    }
                }
                break;
            case 3:
                if (_isSame(pokerGroup)) {
                    isRule = true;
                    pokerGroup.setType(LandlordType.三不带);
                }
                break;
            case 4:
                if (_isSame(pokerGroup)) {
                    isRule = true;
                    pokerGroup.setType(LandlordType.炸弹);
                } else {
                    if (_isThreeLinkOne(pokerGroup)) {
                        pokerGroup.setType(LandlordType.三带一);
                        isRule = true;
                    }
                }
                break;
            case 5:
                if (_isStraight(pokerGroup)) {
                    pokerGroup.setType(LandlordType.单顺子);
                    isRule = true;
                } else {
                }
                break;
            case 6:
                if (_isStraight(pokerGroup)) {
                    pokerGroup.setType(LandlordType.单顺子);
                    isRule = true;
                } else {
                    if (_isTwoStraight(pokerGroup)) {
                        pokerGroup.setType(LandlordType.双顺子);
                        isRule = true;
                    } else {
                        if (_isThreeStraight(pokerGroup)) {
                            pokerGroup.setType(LandlordType.三顺子);
                            isRule = true;
                        } else {
                            if (_isFourLinkTwo(pokerGroup)) {
                                pokerGroup.setType(LandlordType.四带二);
                                isRule = true;
                            }
                        }
                    }
                }
                break;
            case 7:
                if (_isStraight(pokerGroup)) {
                    pokerGroup.setType(LandlordType.单顺子);
                    isRule = true;
                }
                break;
            case 8:
                if (_isStraight(pokerGroup)) {
                    pokerGroup.setType(LandlordType.单顺子);
                    isRule = true;
                } else {
                    if (_isTwoStraight(pokerGroup)) {
                        pokerGroup.setType(LandlordType.双顺子);
                        isRule = true;
                    } else {
                        if (_isThreeFly(pokerGroup)) {
                            pokerGroup.setType(LandlordType.三飞机);
                            isRule = true;
                        }
                    }
                }
                break;
            case 9:
                if (_isStraight(pokerGroup)) {
                    pokerGroup.setType(LandlordType.单顺子);
                    isRule = true;
                } else {
                    if (_isThreeStraight(pokerGroup)) {
                        pokerGroup.setType(LandlordType.三顺子);
                        isRule = true;
                    }
                }
                break;
            case 10:
                if (_isStraight(pokerGroup)) {
                    pokerGroup.setType(LandlordType.单顺子);
                    isRule = true;
                } else {
                    if (_isStraight(pokerGroup)) {
                        pokerGroup.setType(LandlordType.双顺子);
                        isRule = true;
                    }
                }
                break;
            case 11:
                if (_isStraight(pokerGroup)) {
                    pokerGroup.setType(LandlordType.单顺子);
                    isRule = true;
                }
                break;
            case 12:
                if (_isStraight(pokerGroup)) {
                    pokerGroup.setType(LandlordType.单顺子);
                    isRule = true;
                } else {
                    if (_isTwoStraight(pokerGroup)) {
                        pokerGroup.setType(LandlordType.双顺子);
                        isRule = true;
                    } else {
                        if (_isThreeStraight(pokerGroup)) {
                            pokerGroup.setType(LandlordType.三顺子);
                            isRule = true;
                        } else {
                            if (_isThreeFly(pokerGroup)) {
                                pokerGroup.setType(LandlordType.三飞机);
                                isRule = true;
                            } else {
                                if (_isFourFly(pokerGroup)) {
                                    pokerGroup.setType(LandlordType.四飞机);
                                    isRule = true;
                                }
                            }
                        }
                    }
                }
                break;
            case 14:
                if (_isTwoStraight(pokerGroup)) {
                    pokerGroup.setType(LandlordType.双顺子);
                    isRule = true;
                }
                break;
            case 15:
                if (_isThreeStraight(pokerGroup)) {
                    pokerGroup.setType(LandlordType.三顺子);
                    isRule = true;
                }
                break;
            case 16:
                if (_isTwoStraight(pokerGroup)) {
                    pokerGroup.setType(LandlordType.双顺子);
                    isRule = true;
                } else {
                    if (_isThreeFly(pokerGroup)) {
                        pokerGroup.setType(LandlordType.三飞机);
                        isRule = true;
                    }
                }
                break;
            case 18:
                if (_isTwoStraight(pokerGroup)) {
                    pokerGroup.setType(LandlordType.双顺子);
                    isRule = true;
                } else {
                    if (_isThreeStraight(pokerGroup)) {
                        pokerGroup.setType(LandlordType.三顺子);
                        isRule = true;
                    } else {
                        if (_isFourFly(pokerGroup)) {
                            pokerGroup.setType(LandlordType.四飞机);
                            isRule = true;
                        }
                    }
                }
                break;
            case 20:
                if (_isTwoStraight(pokerGroup)) {
                    pokerGroup.setType(LandlordType.双顺子);
                    isRule = true;
                } else {
                    if (_isThreeFly(pokerGroup)) {
                        pokerGroup.setType(LandlordType.三飞机);
                        isRule = true;
                    }
                }
                break;
        }
        return isRule;
    }

    private boolean _isThreeFly(PokerGroup pokerGroup) {
        return isThreeFly(pokerGroup);
    }

    private boolean _isFourFly(PokerGroup pokerGroup) {
        return isFourFly(pokerGroup);
    }

    private boolean _isSame(PokerGroup pokerGroup) {
        return isSame(pokerGroup);
    }

    private boolean _isStraight(PokerGroup pokerGroup) {
        if (hasSpecialPoker(pokerGroup)) {
            return false;
        }
        return isStraight(pokerGroup);
    }

    private boolean _isTwoStraight(PokerGroup pokerGroup) {
        if (hasSpecialPoker(pokerGroup)) {
            return false;
        }
        return isTwoStraight(pokerGroup);
    }

    private boolean _isThreeStraight(PokerGroup pokerGroup) {
        if (hasSpecialPoker(pokerGroup)) {
            return false;
        }
        return isThreeStraight(pokerGroup);
    }

    private boolean _isThreeLinkOne(PokerGroup pokerGroup) {
        return isThreeLinkOne(pokerGroup);
    }

    private boolean _isFourLinkTwo(PokerGroup pokerGroup) {
        return isFourLinkTwo(pokerGroup);
    }

    private boolean hasSpecialPoker(PokerGroup pokerGroup) {
        if (pokerGroup.contains(PokerNum.方块2.value())
                || pokerGroup.contains(PokerNum.小王)
                || pokerGroup.contains(PokerNum.大王)) {
            return true;
        }
        return false;
    }

    @Override
    public boolean hasBigPoker(PokerGroup playerPg, final PokerGroup pg,
                               final List<PokerGroup> list) {
        if (pg.type() == LandlordType.双王) {
            return false;
        }
        if (playerPg.contains(PokerNum.大王) && playerPg.contains(PokerNum.小王)) {
            PokerGroup lp = new PokerGroup();
            lp.addPokerNum(PokerNum.大王);
            lp.addPokerNum(PokerNum.小王);
            isRule(lp);
            addPgToListPokerGroup(list, lp);
            return true;
        }
        // 如果出牌是炸弹
        if (pg.type() == LandlordType.炸弹) {
            // 如果不够4张牌 返回没有
            if (playerPg.size() < 4) {
                return false;
            } else {
                // 如果够4张牌
                List<List<Poker>> lists = getSame(playerPg, 4).filter(
                        new Condition3<Poker>() {

                            @Override
                            public boolean apply(List<Poker> t) {
                                PokerGroup lp = new PokerGroup();
                                lp.addPokers(t);
                                return isRule(lp) && isGreater(lp, pg);
                            }
                        }).toListGroup();
                // 判断有炸弹 返回有
                if (lists.size() >= 1) {
                    addListToListPokerGroup(list, lists);
                    return true;
                } else {
                    return false;
                }
            }
            // 不是炸弹
        } else {
            // 如果够4张牌
            if (playerPg.size() > 4) {
                List<List<Poker>> lists = getSame(playerPg, 4).toListGroup();
                // 判断有炸弹 返回有
                if (lists.size() >= 1) {
                    addListToListPokerGroup(list, lists);
                    return true;
                }
            }
            if (playerPg.size() < pg.size()) {
                return false;
            }
            List<List<Poker>> lists = raListGroup.from1(playerPg.get())
                    .select(pg.size()).filter(new Condition3<Poker>() {

                        @Override
                        public boolean apply(List<Poker> t) {
                            PokerGroup lp = new PokerGroup();
                            lp.addPokers(t);
                            return isRule(lp) && isGreater(lp, pg);
                        }
                    }).toListGroup();
            addListToListPokerGroup(list, lists);
            return lists.size() >= 1;
        }
    }

    private void addListToListPokerGroup(List<PokerGroup> list, List<List<Poker>> listPoker) {
        if (list != null) {
            for (List<Poker> l : listPoker) {
                PokerGroup lp = new PokerGroup();
                lp.addPokers(l);
                list.add(lp);
            }
        }
    }

    private void addPgToListPokerGroup(List<PokerGroup> list, PokerGroup pg) {
        if (list != null) {
            list.add(pg);
        }
    }
}
